package pl.edu.pw.elka.tinyrepo.common;

import java.util.EnumMap;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

/**
 * Klasa reprezentujaca Response. 
 * </br> Analogiczne zachowanie jak w Request.
 *  
 * @see Request 
 * @author Piotr Jarosik
 * @author Anna Stępień
 */
public class Response extends Message
{
   /** Kod statusu response.*/
   private StatusCode code;
   /** Mapa odwzorowujaca rodzaj naglowka na przypisana mu wartosc (np. CONTENT_LENGTH i "text/html"*/
   Map<HTTPHeaderType, String> headers = 
                  new EnumMap<HTTPHeaderType, String>(HTTPHeaderType.class);
   
   /**
    *  Tworzy pusty response.
    */
   public Response() 
   {
   }
   
   /**
    * Tworzy response o podanym kodzie statusu.
    * 
    * @param code
    */
   public Response(StatusCode code) 
   {
      this.code = code;
   }
   
	/** 
	 * Setter kodu statusu.
	 * 
	 * @param status
	 */
	public void setStatusCode(StatusCode status)
	{
		this.code = status;
	}
	
	/**
	 * @return kod statusu w danym Response.
	 */
	public StatusCode getStatusCode() {
		return code;
	}
	
	/**
	 * Czyta pierwsza linie Response i uzupelnia status code.
	 * 
	 * FIXME na razie minimalne sprawdzanie poprawnosci resposne line.
	 * 
	 * @param firstLine
	 */
	public void setFirstLine(String firstLine) {
	   StringTokenizer t = new StringTokenizer(firstLine);
	   String prot = t.nextToken(); // protokol
	   if(!prot.equals("HTTP/1.1"))
	      throw new RuntimeException("Wrong protocol"); // FIXME rzucac innym wyjatkiem
	   String numberString = t.nextToken(); // kod statusu
	   StatusCode c = StatusCode.getType(numberString);
	   if(c == null) 
	      throw new RuntimeException("Wrong status code"); // FIXME rzucac innym wyjatkiem
	   code = c;
	   //FIXME ostatni token pomijam na razie...
	}
	
	@Override
	public String getFirstLine() 
	{
	   return "HTTP/1.1 "+code.getCode()+" "+code.toString();
	}


   @Override
   public String getHeader(HTTPHeaderType t) {
      return headers.get(t);
   }

   @Override
   public void addHeader(HTTPHeaderType t, String value) {
      if(!t.isProperValue(value)) { // zlych wartosci nie wstawiamy
         System.err.println("Wrong "+t+" value.");
         return;
      }
      headers.put(t, value);
   }

   @Override
   public Set<HTTPHeaderType> getHTTPTypes() {
      return headers.keySet();
   }
   
   
   public final Map<HTTPHeaderType, String> getHeaders()
   {
	   return headers;
   }
   
   
   
   
   
   // stare smieci nizej
   
//   @Deprecated
//   public void write(OutputStream out) 
//   {
//      byte[] buffer = new byte[1024]; // FIXME na razie dane sa wysylane bajt po bajcie, jak bedzie cos zamulac to wysylac wiekszymi porcjami
//      try 
//      {
//         out.write((getStatusLine()+"\n").getBytes()); // status line
//         out.write((HTTPHeaderType.CONTENT_TYPE+" "+contentType+"\n").getBytes()); // content type
//         out.write((HTTPHeaderType.CONTENT_LENGTH+" "+data.length+"\n").getBytes()); // content length
//         out.write(("\r\n").getBytes()); // CRLF
//         // wysylanie danych
//         for(byte b: data) 
//            out.write(b); // FIXME wysylanie bajt po bajcie
//      } catch (Exception e) // jak tu sie pojawia problemy to nie ma juz jak powiadomic klienta o tym - mozna tylko wypisac informacje o wyjatku 
//      { 
//         // TODO obsluzyc
//         e.printStackTrace();
//      }
//      finally 
//      {
//         try 
//         {
//            out.close();
//         } 
//         catch (IOException e) 
//         {
//            e.printStackTrace();
//         }
//      }
//   }
}
